#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
交互式研究助理控制台
提供命令行界面与研究助理交互
"""

import os
import sys
import time
import asyncio
import locale
import uuid
from datetime import datetime
from typing import Optional, Any, Union, Coroutine, Awaitable
import argparse

# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)

# 设置默认编码为UTF-8
# 使用更兼容的方式处理编码设置，避免Pylance报错
import io
if hasattr(sys.stdout, 'reconfigure'):
    try:
        # 使用类型忽略注释避免Pylance报错
        sys.stdout.reconfigure(encoding='utf-8')  # type: ignore
        sys.stderr.reconfigure(encoding='utf-8')  # type: ignore
    except (io.UnsupportedOperation, AttributeError):
        pass  # 某些环境下可能不支持
elif hasattr(sys.stdout, 'buffer'):
    # 对于较老的Python版本使用这种方法
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')

from src.services.research_service import ResearchService
from src.config.database import get_db
from src.services.database_session_service import DatabaseSessionService
from src.exceptions import ResearchException, WorkflowExecutionError
from src.utils.logging import get_logger
from src.research_core.model import get_llm
from src.models.session import Session, SessionResponse, SessionStats, SessionInteractionResponse

logger = get_logger(__name__)

class InteractiveResearchConsole:
    """交互式研究助理控制台"""
    
    def __init__(self):
        """初始化控制台"""
        # 检查模型配置
        try:
            print("正在检查模型配置...")
            llm = get_llm()
            print("✅ 模型配置检查通过")
        except Exception as e:
            print(f"❌ 模型配置检查失败: {e}")
            print("请检查环境变量中的模型配置")
            sys.exit(1)
            
        self.research_service = ResearchService()
        self.db = next(get_db())
        self.session_service = DatabaseSessionService(self.db)
        self.session_id: Optional[str] = None
        self.running: bool = True
        
        logger.info("交互式研究助理控制台初始化完成")
    
    def display_welcome(self):
        """显示欢迎信息"""
        print("\n" + "="*60)
        print("🤖 多代理研究系统 - 交互式控制台")
        print("="*60)
        print("输入您的问题进行研究，或输入以下命令:")
        print("  /help     - 显示帮助信息")
        print("  /stats    - 显示会话统计")
        print("  /history  - 查看历史记录")
        print("  /clear    - 清空屏幕")
        print("  /exit     - 退出程序")
        print("="*60)
        print()
    
    def display_help(self):
        """显示帮助信息"""
        print("\n📖 帮助信息:")
        print("- 直接输入问题进行研究，例如: '什么是人工智能?'")
        print("- 问题可以包含上下文，例如: '请解释量子计算的基本原理'")
        print("- 系统会使用多个专业代理进行分析和研究")
        print("- 结果会包含搜索策略、分析过程和最终答案")
        print()
        print("可用命令:")
        print("  /help     - 显示此帮助信息")
        print("  /stats    - 显示当前会话统计")
        print("  /history  - 查看最近的交互历史")
        print("  /clear    - 清空控制台屏幕")
        print("  /exit     - 安全退出程序")
        print()
    
    def clear_screen(self):
        """清空屏幕"""
        os.system('cls' if os.name == 'nt' else 'clear')
        self.display_welcome()
    
    async def initialize_session(self) -> bool:
        """初始化会话"""
        try:
            print("正在初始化会话...")
            # create_session 是同步方法，直接调用
            session_response_coro = self.session_service.create_session("interactive_user")
            # 如果返回的是协程对象，则等待其完成
            if asyncio.iscoroutine(session_response_coro):
                session_response = await session_response_coro
            else:
                session_response = session_response_coro
                
            # 确保正确处理session_response对象
            if session_response and hasattr(session_response, 'id'):
                self.session_id = str(session_response.id)
            else:
                self.session_id = None
                
            if self.session_id:
                logger.info(f"会话已创建: {self.session_id}")
                print(f"✅ 会话初始化成功: {self.session_id}")
                return True
            else:
                logger.error("会话创建失败")
                return False
        except Exception as e:
            logger.error(f"会话初始化失败: {e}")
            return False

    async def display_stats(self):
        """显示会话统计信息"""
        if not self.session_id:
            print("❌ 会话未初始化")
            return
        
        try:
            # 确保 session_id 是 UUID 对象
            session_id = uuid.UUID(self.session_id) if isinstance(self.session_id, str) else self.session_id
            # 直接调用同步方法
            stats_coro = self.session_service.get_session_stats(session_id)
            # 如果返回的是协程对象，则等待其完成
            if asyncio.iscoroutine(stats_coro):
                stats = await stats_coro
            else:
                stats = stats_coro
                
            print(f"\n📈 会话统计信息:")
            print(f"  会话ID: {stats.session_id}")
            print(f"  总交互数: {stats.total_interactions}")
            print(f"  成功研究数: {stats.successful_research}")
            print(f"  失败研究数: {stats.failed_research}")
            print(f"  成功率: {stats.success_rate}")
            print(f"  创建时间: {stats.created_at}")
            print(f"  最后更新: {stats.last_updated}")
            print(f"  活跃状态: {'是' if stats.active else '否'}")
        except Exception as e:
            print(f"❌ 获取统计信息失败: {e}")
    
    async def display_history(self):
        """显示会话历史记录"""
        if not self.session_id:
            print("❌ 会话未初始化")
            return
        
        try:
            session_id = uuid.UUID(self.session_id) if isinstance(self.session_id, str) else self.session_id
            # 直接调用同步方法
            history_coro = self.session_service.get_session_history(session_id, limit=10)
            # 如果返回的是协程对象，则等待其完成
            if asyncio.iscoroutine(history_coro):
                history = await history_coro
            else:
                history = history_coro
                
            if not history:
                print("\n📝 暂无历史记录")
                return
            
            print(f"\n📝 最近 {len(history)} 条历史记录:")
            for i, interaction in enumerate(reversed(history), 1):
                print(f"\n{i}. 问题: {interaction.question}")
                print(f"   答案: {interaction.response.get('answer', interaction.response) if isinstance(interaction.response, dict) else interaction.response}")
                print(f"   时间: {interaction.created_at}")
                print(f"   成功: {'是' if interaction.success else '否'}")
        except Exception as e:
            print(f"❌ 获取历史记录失败: {e}")
    
    async def process_question(self, question: str) -> None:
        """处理用户问题"""
        if not self.session_id:
            print("❌ 会话未初始化")
            return
        
        # 确保问题字符串是有效的UTF-8编码
        try:
            if isinstance(question, bytes):
                question = question.decode('utf-8')
            else:
                question = str(question)
        except Exception:
            question = str(question).encode('utf-8', errors='replace').decode('utf-8')
        
        start_time = time.time()
        
        try:
            print(f"\n🔍 正在研究: {question}")
            print("  正在协调多个专家代理进行分析...")
            
            # 执行研究，增加超时处理
            try:
                # 使用与ResearchService中相同的超时时间 (300秒)
                research_result = await asyncio.wait_for(
                    self.research_service.execute_research(question), 
                    timeout=300.0  # 5分钟超时，与ResearchService中一致
                )
            except asyncio.TimeoutError:
                print("⏰ 请求超时，请稍后重试")
                # 记录超时的交互
                if self.session_service:
                    # 在同步上下文中调用add_interaction
                    self.session_service.add_interaction(
                        session_id=self.session_id, 
                        query=question, 
                        response={"error": "请求超时"},
                        success=False,
                        research_complete=False
                    )
                return
            except asyncio.CancelledError:
                print("🚫 请求被取消，请稍后重试")
                return
            
            result = {
                "answer": research_result.get("final_answer", research_result.get("answer", research_result.get("error", "无答案"))),
                "search_strategy": research_result.get("search_strategy", ""),
                "research_complete": research_result.get("research_complete", research_result.get("success", False)),
                "processing_time": time.time() - start_time
            }
            
            # 记录交互，确保响应内容是有效的UTF-8编码
            if self.session_service:
                try:
                    # 确保响应内容是有效的UTF-8编码
                    response_data = result.copy()
                    if isinstance(response_data.get("answer"), str):
                        response_data["answer"] = response_data["answer"].encode('utf-8', errors='replace').decode('utf-8')
                    if isinstance(response_data.get("search_strategy"), str):
                        response_data["search_strategy"] = response_data["search_strategy"].encode('utf-8', errors='replace').decode('utf-8')
                    
                    self.session_service.add_interaction(
                        session_id=self.session_id, 
                        query=question,
                        response=response_data,
                        success=True,
                        research_complete=response_data.get('research_complete', False)
                    )
                except Exception as e:
                    logger.error(f"记录交互失败: {e}")
            processing_time = result.get('processing_time', time.time() - start_time)
            
            print(f"\n✅ 研究完成 (耗时: {processing_time:.1f}s)")
            print(f"📋 搜索策略: {result.get('search_strategy', '无')}")
            print("\n💡 答案:")
            print("-" * 50)
            answer = result.get('answer', '无答案')
            # 确保答案是有效的UTF-8编码
            answer = answer.encode('utf-8', errors='replace').decode('utf-8')
            print(answer)
            print("-" * 50)
            
            if not result.get('research_complete', False):
                print("⚠️  注意: 研究可能不完整，建议提供更多上下文或重新提问")
                
        except (ResearchException, WorkflowExecutionError) as e:
            error_msg = f"❌ 研究错误: {e}"
            print(error_msg)
            if self.session_service:
                try:
                    self.session_service.add_interaction(
                        session_id=self.session_id,
                        query=question,
                        response={"error": str(e)},
                        success=False,
                        research_complete=False
                    )
                except Exception as db_error:
                    logger.error(f"记录错误交互失败: {db_error}")
            
        except Exception as e:
            error_msg = f"❌ 未知错误: {e}"
            print(error_msg)
            logger.error(f"处理问题失败: {question}", exc_info=True)
            if self.session_service:
                try:
                    self.session_service.add_interaction(
                        session_id=self.session_id,
                        query=question,
                        response={"error": str(e)},
                        success=False,
                        research_complete=False
                    )
                except Exception as db_error:
                    logger.error(f"记录错误交互失败: {db_error}")
    
    async def run(self) -> None:
        """运行控制台"""
        if not await self.initialize_session():
            print("❌ 无法初始化会话，程序将退出")
            return
        
        self.display_welcome()
        
        while self.running:
            try:
                user_input = input(">>> ").strip()
                # 确保输入是正确的UTF-8编码
                if isinstance(user_input, bytes):
                    user_input = user_input.decode('utf-8')
                
                if user_input.lower() == "/help":
                    self.display_help()
                elif user_input.lower() == "/stats":
                    await self.display_stats()
                elif user_input.lower() == "/history":
                    await self.display_history()
                elif user_input.lower() == "/clear":
                    self.clear_screen()
                elif user_input.lower() == "/exit":
                    self.running = False
                elif user_input:  # 只处理非空输入
                    await self.process_question(user_input)
            except KeyboardInterrupt:
                print("\n程序已退出")
                self.running = False
            except EOFError:
                # 处理EOF错误，如管道输入结束
                self.running = False
            except UnicodeDecodeError as e:
                print(f"❌ 输入编码错误: {e}")
                print("请确保使用UTF-8编码输入")

if __name__ == "__main__":
    async def main():
        console = InteractiveResearchConsole()
        await console.run()
    
    asyncio.run(main())